package ihistoryApp.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import ihistoryApp.dal.entity.Message;
import ihistoryApp.dal.entity.User;
import ihistoryApp.dal.mapper.MessageMapper;
import ihistoryApp.dal.mapper.UserMapper;
import ihistoryApp.request.GetChatListRequest;
import ihistoryApp.request.GetLastMessageRequest;
import ihistoryApp.view.LastMessageResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 76004
 * @apiNote
 * @date 2024/5/25 10:55
 */
@Service
@Slf4j
public class MessageService {
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private UserMapper userMapper;

    public List<Message> getChatList(GetChatListRequest request) {
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<Message>()
                .eq(Message::getReceiverId, request.getUid())
                .eq(Message::getSenderId, request.getReceiverId())
                .or((q) -> q.eq(Message::getReceiverId, request.getReceiverId())
                        .eq(Message::getSenderId, request.getUid()))
                .orderByDesc(Message::getTimestamp)
                .select(List.of(Message::getMessageId, Message::getReceiverId, Message::getContent, Message::getTimestamp,
                        Message::getSenderId))
                ;
        List<Message> messageList = messageMapper.selectList(queryWrapper);
        return messageList;
    }


    public List<LastMessageResponse> getLastMessage(GetLastMessageRequest request) {
        LambdaQueryWrapper<Message> messageQuery = new LambdaQueryWrapper<Message>()
                .eq(Message::getReceiverId, request.getUid())
                .or()
                .eq(Message::getSenderId, request.getUid())
                .select(List.of(Message::getMaxMessageId, Message::getReceiverId, Message::getSenderId))
                .groupBy(List.of(Message::getReceiverId, Message::getSenderId))
                ;
        Map<Long, Message> messageMap = messageMapper.selectList(messageQuery).stream().collect(Collectors.toMap((message) -> {
            return message.getReceiverId().equals(request.getUid()) ? message.getSenderId() : message.getReceiverId();
        }, Function.identity(), (a, b) -> {
            a.setMessageId(a.getMaxMessageId());
            b.setMessageId(b.getMaxMessageId());
            if (a.getMaxMessageId() > b.getMaxMessageId()) {
                return a;
            } else {
                return b;
            }
        }));
        return messageMap.entrySet().stream().map(messageM -> {
            LambdaQueryWrapper<Message> messageLambdaQueryWrapper = new LambdaQueryWrapper<Message>()
                    .select(List.of(Message::getMessageId, Message::getContent, Message::getTimestamp))
                    .eq(Message::getMessageId, messageM.getValue().getMaxMessageId())
                    ;
            Message message = messageMapper.selectOne(messageLambdaQueryWrapper);
            LastMessageResponse lastMessageResponse = new LastMessageResponse();
            BeanUtil.copyProperties(message, lastMessageResponse);
            Long otherUid = null;
            User user = userMapper.selectById(messageM.getKey());
            lastMessageResponse.setNickname(user.getNickName());
            lastMessageResponse.setUid(user.getUid());
            log.info("user:{}", JSONUtil.toJsonStr(message));
            return lastMessageResponse;
        }).collect(Collectors.toList());
    }
}